/*
 * Copyright 2007 Dan Hodge
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.datajanitor.baja;

import java.io.File;
import java.io.InputStream;
import java.util.List;

import net.datajanitor.baja.data.BoxFile;
import net.datajanitor.baja.data.BoxFileInfo;
import net.datajanitor.baja.data.UserInfo;

/**
 * Represents a connection to a Box account.
 */
public interface BoxConnection {
    /**
     * Closes the connection.
     */
    public void close();
    
    /**
     * Retrieves information about the user who established this connection.
     * @return The UserInfo for the current user, or null if the connection is no established
     */
    public UserInfo getUser();
    
    /**
     * Gets the root directory.
     * @return The root directory
     * @throws BoxConnectionException If the connection is closed
     */
    public BoxFileInfo getRootDirectory() throws BoxConnectionException;
    
    /**
     * Searches for all files with the specified name from the specfied base directory. 
     * @param name The name of the file
     * @return List of files with the specified name, or an empty list if no matches were found.
     * @throws BoxException If baseDir is invalid or does not exist
     */
    public List<BoxFileInfo> findFileByName(BoxFile baseDir, String name) throws BoxException;
    
    /**
     * Searches for the specified file or directory path and returns the BoxFileInfo object for
     * the path if it exists. 
     * @param path The file or directory path
     * @return The BoxFileInfo object for the path, or null if the path is invalid or does not exist
     */
    public BoxFileInfo getFileByPath(BoxFile path);
    
    /**
     * Downloads the specified file and writes it to the specified file object.
     * @param file The file being downloaded
     * @param toFile The file that it gets downloaded into
     */
    public void downloadFile(BoxFile file, File toFile);
    
    /**
     * Downloads the specified file as an array of bytes. This method should only be
     * used on relatively small files.
     * @param file The file being downloaded
     * @return The downloaded file data
     */
    public byte[] downloadFile(BoxFile file);
    
    /**
     * Streams the specified file.
     * @param file The file being streamed
     * @return An InputStream for the file
     */
    public InputStream streamFile(BoxFile file);
    
    /**
     * Uploads the specified file to the specified directory.
     * @param toDir The parent directory of the file being uploaded
     * @param file The file being uploaded
     * @return The BoxFileInfo object for the newly uploaded file
     */
    public BoxFileInfo uploadFile(BoxFile toDir, File file);
    
    /**
     * Uploads the specified data to the specified directory.
     * @param toDir The parent directory of the file being uploaded
     * @param data The file data
     * @param name The name of the uploaded file
     * @return The BoxFileInfo object for the newly uploaded file
     */
    public BoxFileInfo uploadFile(BoxFile toDir, byte[] data, String name);
    
    /**
     * Uploads the specified stream to the specified directory.
     * @param toDir The parent directory of the file being uploaded
     * @param ins The file data stream
     * @param name The name of the uploaded file
     * @return The BoxFileInfo object for the newly uploaded file
     */
    public BoxFileInfo uploadStream(BoxFile toDir, InputStream ins, String name);
    
    /**
     * Deletes the specified file or directory. This method will only succeed if
     * the file or directory exists and it contains no child files/directories.
     * @param file The file or directory being deleted
     */
    public void delete(BoxFile file);
    
    /**
     * Deletes the specified file or directory. If the file represents a directory,
     * this method will only attempt to delete the directory (and all of its children)
     * if the force flag is set to true. Otherwise, it will throw an exception.
     * @param file The file or directory being deleted
     * @param force true If non-empty directories should be deleted, false if they should not be.
     */
    public void delete(BoxFile file, boolean force);
}
